﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using CC_Util; 
using System.Text;
using System.IO;
using UnityEngine.U2D;
using CS_Util;    

namespace CC_Game {
    public class C_128_AssetsCore {     
        public static C_128_AssetsCore GetInstance() {
            if (instance == null) {
                instance = new C_128_AssetsCore();
                instance.o_Sprite = new C_Sprite();
                instance.o_Texture2 = new C_Texture2D();
                instance.o_txt = new C_Txt();
                instance.o_bytes = new C_Bytes();
    }
            return instance;                                                                         
        }
        static C_128_AssetsCore instance;
        C_128_AssetsCore() { }
        public C_128_AssetBundlePathManage abPathManage = new C_128_AssetBundlePathManage();


        public const string ckey_txt = "txt";
        public const string ckey_bytes = "bytes";
        public const string ckey_prefab = "prefab";
        public const string ckey_spriteatlas = "spriteatlas";
        #region MyRegion ----------加载模型------对象池---------------------------
        /// <summary>
        /// 从对象池中获取模型--
        /// </summary>
        public GameObject S_GetModel(int aa,int bb,int cc,int dd, ushort batchCloneNumber = 5, Transform father = null) {
            return S_GetModel(C_Int4.Get(aa,bb,cc,dd), batchCloneNumber, father);
        }
        /// <summary>
        /// 从对象池中获取模型--
        /// </summary>
        public GameObject S_GetModel(int[] path, ushort batchCloneNumber =5, Transform father = null) {
            if (path==null||path.Length < 4) {
                C_Log.LogError("读取模型出错__路径参数不完整");
                return null;
            }
            return S_GetModel(C_Int4.Get(path), batchCloneNumber, father);
        }
        /// <summary>
        /// 从对象池中获取模型--
        /// </summary>
        public GameObject S_GetModel(C_Int4 onlyPath, ushort batchCloneNumber = 3,Transform father=null) {
            if (_deathDic.ContainsKey(onlyPath)==false) {
                _deathDic[onlyPath] = new List<GameObject>();
            }
            List<GameObject> list = _deathDic[onlyPath];
            ddd:
            if (list.Count == 0) {
                string path = null;
                GameObject gg0 = null;
                if (abPathManage.o_prefabPathDic.ContainsKey(onlyPath)) {
                    path = abPathManage.o_prefabPathDic[onlyPath];
                }
                if (path == null) {
                    if(onlyPath == e_nullArt) {
                        gg0 = new GameObject("nullArt");
                    } else {
                        C_Log.LogErrorFormat("严重错误___模型路径不存在___{0}".S_SetColor("ff0066"), onlyPath);
                        return null;
                    }
                } else {
                    gg0 = S_GetAsset<GameObject>(path, true);
                }
          
                gg0.transform.SetParent(ObjectPoolFather);
                gg0.SetActive(false);
                list.Add(gg0);
                if (_modelOriginScaleDic.ContainsKey(onlyPath) == false) {
                    _modelOriginScaleDic[onlyPath] = gg0.transform.localScale;
                }
            }
            if (list.Count == 1) {
                if (batchCloneNumber > 1) {
                    GameObject gg0 = list[0];
                    if (gg0 == null) {
                        list.RemoveAt(0);
                        C_Log.LogErrorFormat("美术资源被恶意删除_____________{0}_", onlyPath);
                        goto ddd;
                    }
                    for (int i = 0; i < batchCloneNumber-1; i++) {
                        GameObject gg2 = GameObject.Instantiate(gg0);
                        gg2.transform.SetParent(ObjectPoolFather);
                        list.Add(gg2);
                    }
                }
            }
            int index = list.Count - 1;
            GameObject gg = list[index];
            if (father != null) {
                gg.transform.SetParent(father);
            }
            gg.SetActive(true);
            list.RemoveAt(index);
            return gg;
        }
        public C_Int4 e_nullArt = C_Int4.Get(0, 0, 0, 1);
        public Vector3 S_GetModelOriginScale(C_Int4 onlyPath) {
            if (_modelOriginScaleDic.ContainsKey(onlyPath)) {
                return _modelOriginScaleDic[onlyPath];
            } else {
                GameObject gg = S_GetModel(onlyPath, 1);
                S_AddDeathModel(onlyPath, gg);
                return S_GetModelOriginScale(onlyPath);
            }
        }
        public void S_SetModelOriginScale(C_Int4 onlyPath,Vector3 scale) {
            _modelOriginScaleDic[onlyPath] = scale;
        }
        /// <summary>
        /// 物体死亡 添加到对象池
        /// </summary>
        public void S_AddDeathModel(C_Int4 onlyPath, GameObject gg0) {
            if (_deathDic.ContainsKey(onlyPath) == false) {
                _deathDic[onlyPath] = new List<GameObject>();
            }
            gg0.SetActive(false);
            _deathDic[onlyPath].Add(gg0);
 
        }
        public void S_AddDeathModel(int[] path, GameObject gg0) {
            if (path == null || path.Length < 4) {
                C_Log.LogError("读取模型出错__路径不完整");
            }
            S_AddDeathModel(C_Int4.Get(path), gg0);
        }
        /// <summary>
        /// 物体死亡 添加到对象池
        /// </summary>
        public void S_AddDeathModel(int aa, int bb, int cc, int dd, GameObject gg0) {
            S_AddDeathModel(C_Int4.Get(aa,bb,cc,dd), gg0);
        }
        /// <summary>
        /// 对象池父
        /// </summary>
        Dictionary<C_Int4, List<GameObject>> _deathDic = new Dictionary<C_Int4, List<GameObject>>();
        /// <summary>
        /// 模型原始缩放
        /// </summary>
        Dictionary<C_Int4, Vector3> _modelOriginScaleDic = new Dictionary<C_Int4, Vector3>();
        /// <summary>
        /// 对象池父物体
        /// </summary>
        public Transform ObjectPoolFather {
            get {
                if (objectPoolFather == null) {
                    objectPoolFather = new GameObject("C_128_AssetsCore.Father").transform;
                }
                return objectPoolFather;
            }
        }
        Transform objectPoolFather;
        #endregion


        public C_Sprite o_Sprite;
        public C_Texture2D o_Texture2;
        public C_Txt o_txt;
        public C_Bytes o_bytes;



        #region MyRegion ----------资源加载---------------------------
        public class C_Sprite : C_Assets00<Sprite> {
            internal C_Sprite() {  }

            public override Sprite Get(C_Int4 onlyPath, bool isForceReLoad = false) {
                if (onlyPath == null || onlyPath == C_Int4.zero) {
                    return null;
                }
                if (o_assetsObjDic.ContainsKey(onlyPath) && isForceReLoad==false) {
                    return o_assetsObjDic[onlyPath];
                } else {
                    string path = null;
                    if (C_128_AssetsCore.instance.abPathManage.o_spriteatlasPathDic.ContainsKey(onlyPath)) {
                        path = C_128_AssetsCore.instance.abPathManage.o_spriteatlasPathDic[onlyPath];
                        SpriteAtlas[] atlass = C_128_AssetsCore.instance.S_GetAssetAll<SpriteAtlas>(path);
                        if (atlass == null) {
                            C_Log.LogErrorFormat("loadFail.读取资源错误...___{0}___{1}", onlyPath, path);
                        }
                        Sprite[] array = new Sprite[atlass[0].spriteCount];
                        atlass[0].GetSprites(array);
                        for (int i = 0; i < array.Length; i++) {
                            C_Int4 onlyPath0 = C_Int4.Get(array[i].name);
                            if (onlyPath0 != C_Int4.zero) {
                                o_assetsObjDic[onlyPath0] = array[i];
                            }
                        }
                    } else if (C_128_AssetsCore.instance.abPathManage.o_texturePathDic.ContainsKey(onlyPath)) {
                        path = C_128_AssetsCore.instance.abPathManage.o_texturePathDic[onlyPath];
                        Sprite[] sprites = C_128_AssetsCore.instance.S_GetAssetAll<Sprite>(path);
                        if (sprites == null) {
                            C_Log.LogErrorFormat("loadFail.读取资源错误...___{0}___{1}", onlyPath, path);
                        }
                        for (int i = 0; i < sprites.Length; i++) {
                            C_Int4 onlyPath0 = C_Int4.Get(sprites[i].name);
                            if (onlyPath0 != C_Int4.zero) {
                                o_assetsObjDic[onlyPath0] = sprites[i];
                            }
                        }
                    } else {
                        C_Log.LogFormat(string.Format("loadFail.严重错误___图标不存在___{0}_{1}", onlyPath, isForceReLoad).S_SetColor("ff0066"));
                        return null;
                    }
                    return Get(onlyPath);
                }
            }
        }
        public class C_Texture2D: C_Assets00<Texture2D> {
            internal C_Texture2D() { _tag = "Texture2D"; _assetsPathDic = C_128_AssetsCore.instance.abPathManage.o_texturePathDic; }
        }
        public class C_Txt : C_Assets00<TextAsset> {
            internal C_Txt() { _tag = "Txt"; _assetsPathDic = C_128_AssetsCore.instance.abPathManage.o_txtPathDic; }
        }
        public class C_Bytes : C_Assets00<TextAsset> {
            internal C_Bytes() { _tag = "bytes"; _assetsPathDic = C_128_AssetsCore.instance.abPathManage.o_bytesPathDic; }
        }
        public class C_Assets00<T>where T: UnityEngine.Object {
            protected Dictionary<C_Int4, T> o_assetsObjDic = new Dictionary<C_Int4, T>();
            protected Dictionary<C_Int4, string> _assetsPathDic;
            protected string _tag;
            public T S_Get(int[] path, bool isForceReLoad = false) {
                if (path == null || path.Length < 4) {
                    C_Log.LogErrorFormat("读取 {0} 出错__路径不完整", _tag);
                }
                return Get(C_Int4.Get(path), isForceReLoad);
            }
            public T S_Get(int a, int b, int c, int d, bool isForceReLoad = false) {
                return Get(C_Int4.Get(a, b, c, d), isForceReLoad);
            }
            public virtual T Get(C_Int4 onlyPath,bool isForceReLoad=false) {
                T texture = null;
                if (o_assetsObjDic.ContainsKey(onlyPath)&& isForceReLoad==false) {
                    texture = o_assetsObjDic[onlyPath];
                } else {
                    if (_assetsPathDic.ContainsKey(onlyPath) == false) {
                        C_Log.LogErrorFormat(("loadFail.严重错误.{0}._____.{1}___路径不存在").S_SetColor("ff0066"), _tag,onlyPath);
                        return null;
                    }
                    string path = _assetsPathDic[onlyPath];
                    T[] txts = C_128_AssetsCore.GetInstance().S_GetAssetAll<T>(path);
                    if (txts == null || txts.Length == 0 || txts[0] == null) {
                        C_Log.LogErrorFormat(("loadFail.严重错误.{0},{1}___不存在").S_SetColor("ff0066"), _tag, onlyPath);
                        return null;
                    }
                    o_assetsObjDic[onlyPath] = txts[0];
                    return Get(onlyPath);
                }
                return texture;
            }
        }
        #endregion--------------------------------------------





        public T S_GetAsset<T>(string prefabName, bool isClone = true) where T : UnityEngine.Object {
            T[] objs = S_GetAssetAll<T>(prefabName);
            if (objs != null && objs.Length > 0) {
                T obj = objs[0];
                if (obj != null) {
                    if (isClone) {
                        if (typeof(T) == typeof(GameObject)) {
                            GameObject gg = obj as GameObject;
                            //gg.name = prefabName;
                            GameObject gg2 = GameObject.Instantiate(gg);
                            if (C_LoadAssetBundles.GetInstance.o_IsResourcesLoad == false) {
                                C_Tools.S_FixShader(gg2);
                            }
                            obj = gg2 as T;
                        }
                    }
                } else {
                    C_Log.LogError(("_超级错误____" + prefabName + "___不存在_").S_SetColor("ff0066"));
                }
                return obj;
            } else {
                C_Log.LogError(("_超级错误____" + prefabName + "___不存在_").S_SetColor("ff0066"));
                return null;
            }
        }
        public T[] S_GetAssetAll<T>(string prefabName) where T : UnityEngine.Object {
            T[] objs = null;
            //C_Log.Log(("加载Assets____________" + prefabName).S_SetColor("996699"));
            if (C_LoadAssetBundles.GetInstance.o_IsResourcesLoad == true) {
                string[] sss3 = prefabName.Split(new string[] { "Resources/", "Resources\\", ".prefab",".png",".jpg", ".tif", ".txt",".spriteatlas" }, StringSplitOptions.RemoveEmptyEntries);
                //string path=Path.GetFileNameWithoutExtension(sss3[1]);
                //C_Log.Log("---C_LoadAssetBundles--------" + path);
                objs= Resources.LoadAll<T>(sss3[1]);
            } else {
                prefabName = C_String.S_消除中文字符(prefabName);
                AssetBundlePackage ab = C_LoadAssetBundles.GetInstance.S_LoadAssetBundleFromFile(prefabName);
                if (ab != null) {
                    AssetBundle mobelAB = ab.assetBundle;
                    T[] objs0 = mobelAB.LoadAllAssets<T>();
                    for(int i=0;i< objs0.Length; i++) {
                        objs0[i].name = prefabName + "_" + i;
                    }
                    if (objs0 != null) {
                        objs = objs0;
                    } else {
                        objs = null;
                    }
                } else {
                    objs= null;
                }
            }
            return objs;
        }

        public void S_LoadScene(string assetBundleFullName, Action<float> progreEvent, Action finishCallBack) {
            C_MonoMonitor.mono.S_delay(0).d_delayEndEvent = delegate () {
                bool autoJump = true;
                string sceneName = Path.GetFileNameWithoutExtension(assetBundleFullName);
                if (C_LoadAssetBundles.GetInstance.o_IsResourcesLoad == true) {
                    //Debug.LogFormat("加载场景____{0}________prefabName2=={1}", assetBundleFullName, sceneName);
                    AsyncOperation async = SceneManager.LoadSceneAsync(sceneName);
                    C_MonoMonitor.mono.StartCoroutine(I_LoadScene(async, progreEvent, finishCallBack));
                } else {
                    C_LoadAssetBundles.GetInstance.LoadScene(C_MonoMonitor.mono, assetBundleFullName, autoJump, sceneName, progreEvent, finishCallBack);
                }
            };
        }
        IEnumerator I_LoadScene(AsyncOperation async, Action<float> progreEvent, Action finishCallBack) {
            //async.completed += delegate (AsyncOperation ddd) {
            //    C_Log.Log("------场景加载完成了---------progre==" + async.progress);
            //};
            //yield return async;
            async.allowSceneActivation = false;
            async.priority = 50;
            float targetValue, currentValue=0;
            float loadingSpeed = 1;
            while (async.isDone == false) {
                targetValue = async.progress;
                if (async.progress >= 0.9f) {
                    targetValue = 1;
                }
                if (targetValue != currentValue) {
                    currentValue = Mathf.Lerp(currentValue, targetValue, Time.deltaTime * loadingSpeed);
                    if (Mathf.Abs(currentValue - targetValue) < 0.01f) {
                        currentValue = targetValue;
                    }
                }

                if (progreEvent != null) {
                    progreEvent(currentValue);
                }
                //Debug.LogFormat("---------------progre=={0}____currentValue=={1}_____deltaTime=={2}___", async.progress, currentValue,Time.deltaTime);
                yield return new WaitForSeconds(0);
                if ((int)(currentValue * 100) == 100) {
                    async.allowSceneActivation = true;
                }
            }
            if (finishCallBack != null) {
                try {
                    finishCallBack();
                }catch(Exception ex) {
                    C_Log.LogErrorInfo("#ff0088#超级错误", ex);
                }
            }
        }
        public void S_SetAssetsRootPath(string rootPath) {
            C_LoadAssetBundles.GetInstance.S_InitRootPath(rootPath);
        }
        internal class C_LoadAssetBundles {
            //注意  所有的 AssetBundlePackage读取 只能同步读取 因为牵扯到递归加载 
            //但是 AssetBundlePackage的每一个 具体的 asset资源 可以使用异步加载 
            private static C_LoadAssetBundles instance;
            public static C_LoadAssetBundles GetInstance {
                get {
                    if (instance == null) {
                        instance = new C_LoadAssetBundles();
                        instance.S_InitRootPath(null);
                    }
                    return instance;
                }
            }
            public bool o_IsResourcesLoad;
#if UNITY_ANDROID
            string platform = "Android";
#elif UNITY_IPHONE
            string platform = "IOS";
#else
            string platform = "WindowsEditor";
#endif
            /// <summary>
            ///  assetbundle位置的根目录   默认的是所有的assetbundle 都放在一个文件夹下   
            /// </summary>
            public string ResourceRootPath;
            public string MainfestName;
            /// <summary>
            /// 上一个场景的ab
            /// </summary>
            private AssetBundle lastSceneBundle = null;
            /// <summary>
            ///  缓存AssetBundlePackage字典
            /// </summary>
            public Dictionary<string, AssetBundlePackage> allAssetBundleDic = new Dictionary<string, AssetBundlePackage>();
            public Dictionary<string, AssetBundle> dependsAssetbundleList = new Dictionary<string, AssetBundle>();
            /// <summary>
            ///  主要记录AssetBundle 之间的互相引用
            /// </summary>
            private AssetBundleManifest manifest;
            public void S_InitRootPath(string resourceRootPath) {
                if (string.IsNullOrEmpty(resourceRootPath)) {
                    o_IsResourcesLoad = true;
                } else {
                    o_IsResourcesLoad = false;
                    if (resourceRootPath[resourceRootPath.Length - 1] != '/') {
                        resourceRootPath += "/";
                    }
                    Caching.ClearCache();
                    ResourceRootPath = resourceRootPath;
                    MainfestName = platform;
                    GetAssetBundleManifest();
                }
//#if !UNITY_EDITOR
//                o_IsResourcesLoad = false;
//#endif  
            }
            /// <summary>
            ///  拿到AssetBundleManifest 以便于收集 所有的assetbundle 依赖
            /// </summary>
            private void GetAssetBundleManifest() {
                AssetBundle manifestAB = AssetBundle.LoadFromFile(ResourceRootPath + MainfestName);  // 加载总ManifestAssetBundle
                if (manifestAB != null) {
                    manifest = (AssetBundleManifest)manifestAB.LoadAsset("AssetBundleManifest");
                    manifestAB.Unload(false);  // 释放AssetBundle
                } else {
                    C_Log.LogError("加载MainfestName报错----------" + ResourceRootPath + MainfestName+ ".manifest");
                }
            }
            /// <summary>
            ///  异步加载场景
            /// </summary>
            internal void LoadScene(MonoBehaviour mono,string assetBundleName, bool autoJump, string sceneName, Action<float> progreEvent, Action finishCallBack) {
                mono.StartCoroutine(I_LoadScene(assetBundleName, autoJump, sceneName, progreEvent, finishCallBack));
            }
            /// <summary>
            ///  加载场景
            /// </summary>
            IEnumerator I_LoadScene(string assetBundleName, bool autoJump, string sceneName, Action<float> progreEvent, Action finishCallBack) {
                C_Log.Log("## LoadScene " + sceneName);
                assetBundleName = assetBundleName.ToLower();

                string[] list = manifest.GetAllDependencies(assetBundleName);
                if (list.Length != 0) {
                    for (int i = 0; i < list.Length; i++) {
                        //加载所有的依赖文件;  
                        //C_Log.Log("加载的资源是 =" + ResourceRootPath + list[i]);
                        if (!dependsAssetbundleList.ContainsKey(list[i])) {
                            dependsAssetbundleList.Add(list[i], AssetBundle.LoadFromFile(ResourceRootPath + list[i]));
                        }
                    }
                }

                if (!allAssetBundleDic.ContainsKey(assetBundleName)) {
                    C_Log.Log("LoadScene-url----file://" + ResourceRootPath + assetBundleName);
                    WWW www = WWW.LoadFromCacheOrDownload("file://" + ResourceRootPath + assetBundleName, 0);
                    yield return www;
                    if (www.error != null) {
                        C_Log.Log("## LoadScene fail---" + assetBundleName+"___"+www.error);
                        if (finishCallBack != null) {
                            finishCallBack();
                        }
                        yield break;
                    }
              
                    AssetBundle bundle = www.assetBundle;
                    if (finishCallBack != null && autoJump && !string.IsNullOrEmpty(sceneName)) {
                        //这里会报错主要出现在加载大厅场景和中发白场景的时候
                        //报错提示 Assertion failed on expression: 'Thread::CurrentThreadIsMainThread()' 可以查一下问题
                        AsyncOperation ab = SceneManager.LoadSceneAsync(sceneName);
                        yield return ab;
                        Resources.UnloadUnusedAssets();
                        if (lastSceneBundle != null) {
                            lastSceneBundle.Unload(true);
                            lastSceneBundle = null;
                        }
                        lastSceneBundle = bundle;
                        C_Log.Log("## LoadScene finish-----" + sceneName);
                        finishCallBack();
                    } else {
                        C_Log.Log("## LoadScene finish2---" + sceneName);
                        if (finishCallBack != null) {
                            finishCallBack();
                        }
                    }
                } else {
                    SceneManager.LoadScene(sceneName);
                    Resources.UnloadUnusedAssets();
                    yield return null;
                }
            } 
            /// <summary>
            ///  备注 LoadFromMemory 垃圾
            ///  一般来说，尽可能使用AssetBundle.LoadFromFile。该API在速度，磁盘使用率和运行时内存使用方面是最有效的
            /// </summary>
            public AssetBundlePackage S_LoadAssetBundleFromFile(string assetBundleName) {                                                          
                assetBundleName = assetBundleName.ToLower();
                if (!allAssetBundleDic.ContainsKey(assetBundleName)) {
                    C_Log.Log(("加载AssetBundle____________________"+ assetBundleName).S_SetColor("8844ff"));
                    string[] list = manifest.GetAllDependencies(assetBundleName);
                    if (list.Length != 0) {
                        for (int i = 0; i < list.Length; i++) {
                            //加载所有的依赖文件;  
                            //C_Log.Log("加载的资源是 =" + ResourceRootPath + list[i]);
                            if (!dependsAssetbundleList.ContainsKey(list[i])) {
                                dependsAssetbundleList.Add(list[i], AssetBundle.LoadFromFile(ResourceRootPath + list[i]));
                            }
                        }
                    }
                    AssetBundle bundle;
                    if (dependsAssetbundleList.ContainsKey(assetBundleName)) {
                        bundle = dependsAssetbundleList[assetBundleName];
                    } else {
                        bundle = AssetBundle.LoadFromFile(ResourceRootPath + assetBundleName);
                    }
                    AssetBundlePackage tmpAssetBundle = new AssetBundlePackage(bundle, assetBundleName);
                    S_AddAssetBundleToDic(tmpAssetBundle);
                    return tmpAssetBundle;
                } else {
                    return allAssetBundleDic[assetBundleName];
                }
            }
            void S_AddAssetBundleToDic(AssetBundlePackage bundle) {
                if (!allAssetBundleDic.ContainsKey(bundle.name)) {
                    allAssetBundleDic.Add(bundle.name, bundle);
                } else {
                    C_Log.Log("资源加载重复");
                }
            }
        }
        internal class AssetBundlePackage {
            public string name;
            public AssetBundle assetBundle;
            private Dictionary<string, UnityEngine.Object> cacheDic;
            public Dictionary<string, UnityEngine.Object> CacheDic {
                set {
                    cacheDic = value;
                }
                get {
                    if (cacheDic == null) {
                        cacheDic = new Dictionary<string, UnityEngine.Object>();
                    }
                    return cacheDic;
                }
            }
            public AssetBundlePackage(AssetBundle bundle, string n) {
                n = n.ToLower();
                name = n;
                assetBundle = bundle;
            }
            public void Unload(bool t) {
                if (assetBundle != null) {
                    if (t) {
                        CacheDic.Clear();
                        assetBundle.Unload(t);
                        CacheDic = null;
                        assetBundle = null;
                        name = null;
                    } else {
                        assetBundle.Unload(t);
                        CacheDic = null;
                        assetBundle = null;
                    }
                }
            }
            /// <summary>
            ///  通过缓存读取 文件 比如很多情况下读取图片会有很多次 那么如果不缓存的话就会形成很多副本 
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public T LoadAssetWithCache<T>(string name) where T : UnityEngine.Object {
                //
                if (CacheDic.ContainsKey(name)) {
                    return CacheDic[name] as T;
                } else {
                    T t1 = assetBundle.LoadAsset<T>(name);
                    if (t1 != null) {
                        CacheDic.Add(name, t1);
                        return t1;
                    } else {
                        return null;
                    }
                }
            }
            /// <summary>
            ///  通过缓存读取 文件 比如很多情况下读取图片会有很多次 那么如果不缓存的话就会形成很多副本 
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public UnityEngine.Object LoadAssetWithCache(string name) {
                if (CacheDic.ContainsKey(name)) {
                    return CacheDic[name];
                } else {
                    UnityEngine.Object t1 = assetBundle.LoadAsset(name);
                    if (t1 != null) {
                        CacheDic.Add(name, t1);
                        return t1;
                    } else {
                        return null;
                    }
                }
            }
            /// <summary>
            ///  缓存所有的包内资源 
            /// </summary>
            public void CacheAllAsset() {
                UnityEngine.Object[] assetArray = assetBundle.LoadAllAssets();
                for (int i = 0; i < assetArray.Length; i++) {
                    UnityEngine.Object asset = assetArray[i];
                    if (!CacheDic.ContainsKey(asset.name)) {
                        CacheDic.Add(asset.name, asset);
                    }
                }
            }
        } 
    }
    public class C_128_AssetBundlePathManage {
        public Dictionary<C_Int4, string> o_prefabPathDic = new Dictionary<C_Int4, string>();
        public Dictionary<C_Int4, string> o_texturePathDic = new Dictionary<C_Int4, string>();
        public Dictionary<C_Int4, string> o_spriteatlasPathDic = new Dictionary<C_Int4, string>();
        public Dictionary<C_Int4, string> o_txtPathDic = new Dictionary<C_Int4, string>();
        public Dictionary<C_Int4, string> o_bytesPathDic = new Dictionary<C_Int4, string>();


        void S_AddPath00(int aa,int bb, int cc, int dd, string path) {
            S_AddPath00(C_Int4.Get(aa, bb, cc, dd), path);
        }
        void S_AddPath00(C_Int4 onlyPath, string fullPath) {
            //Debug.LogFormat("注册 C_Int4 资源____.{0}.___{1}_", onlyPath, path);
            string path, extension = null;
            S_GetPath_Extension(fullPath, out path,out extension);
            if (extension == C_128_AssetsCore.ckey_spriteatlas) {
                o_spriteatlasPathDic[onlyPath] = path;
            } else if (extension == C_128_AssetsCore.ckey_prefab) {
                o_prefabPathDic[onlyPath] = path;
                S_Show_AddPrefab(onlyPath, path);
            } else if (extension == C_128_AssetsCore.ckey_txt) {
                o_txtPathDic[onlyPath] = path;
            } else if (extension == C_128_AssetsCore.ckey_bytes) {
                o_bytesPathDic[onlyPath] = path;
            } else {
                o_texturePathDic[onlyPath] = path;
            }
        }
        public static void S_AddOnlyPath(int aa, int bb, int cc, int dd, string path) {
            C_128_AssetsCore.GetInstance().abPathManage.S_AddPath00(aa,bb,cc,dd,path);
        }
        public static void S_AddOnlyPath(C_Int4 onlyPath, string path) {
            C_128_AssetsCore.GetInstance().abPathManage.S_AddPath00(onlyPath, path);
        }
        public C_Int4[] S_GetPrefabArrayA(int aMin = 0, int aMax = 0) {
            if (aMax == 0 && aMin == 0) {
                aMin = -256;
                aMax = 256;
            }
            if (aMin > aMax) {
                aMax = aMin;
            }
            return o_prefabPathDic.Keys.Where(n => n.a >= aMin && n.a <= aMax).ToArray();
        }
        public C_Int4[] S_GetPrefabArrayB(int a, int bMin = 0, int bMax = 0) {            
            if(bMax == 0 && bMin == 0) {
                bMax = 32;
            }
            if (bMin> bMax) {
                bMax = bMin;
            }
            return o_prefabPathDic.Keys.Where(n => n.a == a && n.b >= bMin && n.b <= bMax).ToArray();
        }
        public C_Int4[] S_GetPrefabArrayC(int a, int b,int cMin=0,int cMax=0) {
            if (cMax == 0 && cMin == 0) {
                cMax = 512;
            }
            if (cMin > cMax) {
                cMax = cMin;
            }
            return o_prefabPathDic.Keys.Where(n => n.a == a && n.b == b && n.c >= cMin && n.c <= cMax).ToArray();
        }
        public C_Int4[] S_GetPrefabArrayD(int a, int b, int c, int dMin = 0, int dMax = 0) {
            if (dMax == 0 && dMin == 0) {
                dMax = 512;
            }
            if (dMin > dMax) {
                dMax = dMin;
            }
            return o_prefabPathDic.Keys.Where(n => n.a == a && n.b == b && n.c == c && n.d >= dMin && n.d <= dMax).ToArray();
        }




        #region---------------------------工具方法----------------------
        /// <summary>
        /// 根据图片路径才分出来多个sprite
        /// </summary>
        static List<int> S_GetSpriteList(string prefabFullPath) {
            string[] sss3 = prefabFullPath.Split(new string[] { "Resources/", ".png", ".jpg", ".tif" }, StringSplitOptions.RemoveEmptyEntries);
            Sprite[] sprites = Resources.LoadAll<Sprite>(sss3[1]);
            List<int> list = new List<int>();
            for (int i = 0; i < sprites.Length; i++) {
                try {
                    int ii = int.Parse(sprites[i].name);
                    list.Add(ii);
                } catch { }
            }
            return list;
        }
        /// <summary>
        /// 获取路径 和 后缀名
        /// </summary>
        static void S_GetPath_Extension(string fullPath,out string path, out string extension) {
            int index = fullPath.LastIndexOf('.');
            path = fullPath.Substring(0, index);//---路径
            extension = fullPath.Substring(index+1);//--后缀名
        }
        /// <summary>
        /// 获取路径文件名
        /// </summary>
        static string S_GetFileName(string path) {
            string[] sss = path.Split(new char[] { '\\', '/' });
            return sss[sss.Length - 1];
        }
        #endregion------------------------------------------




        public static void S_RegisterArtList() {
            TextAsset[] objs = Resources.LoadAll<TextAsset>("fileList");
            for (int v = 0; v < objs.Length; v++) {
                string[] sss = objs[v].text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                S_RegisterArtList(sss);
            }
        }

        public static void S_RegisterArtList_Editor() {
            //TextAsset[] objs = Resources.LoadAll<TextAsset>("fileList");
            FileInfo[] fileInfos = new DirectoryInfo(Application.dataPath).GetFiles("*fileList.txt", SearchOption.AllDirectories);
            for (int v = 0; v < fileInfos.Length; v++) {
                string[] sss = File.ReadAllLines(fileInfos[v].FullName);
                S_RegisterArtList(sss);
            }
        }

        static void S_RegisterArtList(string[] sss) {
            //C_Log.LogErrorFormat("{0}.....{1}", v, objs[v].text);
         
            for (int c = 0; c < sss.Length; c++) {
                string[] sss2 = sss[c].Split(C_String.e_split06);
                for (int s = 0; s < sss2.Length; s++) {
                    try {
                        C_Int4 onlyPath = C_Int4.Get(sss2[0]);
                        S_AddOnlyPath(onlyPath, sss2[1]);
                    } catch { }
                }
            }
        }

        public Dictionary<int, Dictionary<int, Dictionary<C_Int4, string>>> o_show_onlyPathDic = new Dictionary<int, Dictionary<int, Dictionary<C_Int4, string>>>();
        void S_Show_AddPrefab(C_Int4 onlyPath, string path) {
            if (o_show_onlyPathDic.ContainsKey(onlyPath.a) == false) {
                o_show_onlyPathDic[onlyPath.a] = new Dictionary<int, Dictionary<C_Int4, string>>();
            }
            if (o_show_onlyPathDic[onlyPath.a].ContainsKey(onlyPath.b) == false) {
                o_show_onlyPathDic[onlyPath.a][onlyPath.b] = new Dictionary<C_Int4, string>();
            }
            o_show_onlyPathDic[onlyPath.a][onlyPath.b][onlyPath] = path;
        }
        #region----------Editor---工具方法-------------------------
        /// <summary>
        /// 给每个资源库生成一个资源列表
        /// </summary>
        public static string S_Create_onlyPathCode(Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic, string namespace0) {
            //Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic = S_GetOnlyPathDic(assetsOnlyPathList);
            if (onlyPath_PathDic.Count == 0) {
                return null;
            }

            StringBuilder ssb = new StringBuilder();
            string ss3 = @"


/// <summary>
/// 当前代码是由程序生成------满足安数字编号查找-------------
/// </summary>
using CC_Game;
namespace namespace0 {
    public class ResourcesPath {     
";
            ss3 = ss3.Replace("namespace0", namespace0);
            ssb.Append(ss3);
            ssb.AppendFormat("\t\tpublic static void S_SetPathToDic() {{\n");

            int length = Application.dataPath.Length + 1;
            int ii = 0;
            var dic0 = onlyPath_PathDic.GetEnumerator();
            while (dic0.MoveNext()) {
                var dic = dic0.Current.Value.GetEnumerator();
                while (dic.MoveNext()) {
                    C_Int4 onlyPath = dic.Current.Key;
                    string path = dic.Current.Value.Substring(length);
                    ssb.AppendFormat("\t\t\tAssetBundlePathManage.S_AddOnlyPath({0},{1},{2},{3},\"{4}\" );\n", onlyPath.a, onlyPath.b, onlyPath.c, onlyPath.d, path);
                    ii++;
                }
            }
            if (ii == 0) {
                return null;
            }
            ssb.Append("\t\t}\n\t}\n}");
            return ssb.ToString();
        }
        public static string S_Create_onlyPathTxt(Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic) {
            //Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic = S_GetOnlyPathDic(assetsOnlyPathList);
            if (onlyPath_PathDic.Count == 0) {
                return null;
            }
            int ii = 0;
            StringBuilder ssb = new StringBuilder();
            int length = Application.dataPath.Length + 1;
            var dic0 = onlyPath_PathDic.GetEnumerator();
            while (dic0.MoveNext()) {
                var dic = dic0.Current.Value.GetEnumerator();
                while (dic.MoveNext()) {
                    C_Int4 onlyPath = dic.Current.Key;
                    string path = dic.Current.Value.Substring(length);
                    ssb.AppendFormat("{0}{1}{2}{3}\r\n", onlyPath.ToString(),C_String.e_split06, path, C_String.e_split06);
                    ii++;
                }
            }
            if (ii == 0) {
                return null;
            }
            return ssb.ToString();
        }


       /// <summary>
       /// 根据路径信息，获取资源集合
       /// </summary>
       /// <param name="onlyPathList"></param>
       /// <returns></returns>
       public static Dictionary<string, Dictionary<C_Int4, string>> S_GetOnlyPathDic(List<string> onlyPathList) {
            Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic = new Dictionary<string, Dictionary<C_Int4, string>>();
            for (int k = 0; k < onlyPathList.Count; k++) {
                string fullPath = onlyPathList[k];
                string name = S_GetFileName(fullPath);
                string path, extension = null;
                S_GetPath_Extension(fullPath, out path, out extension);
                if (extension == C_128_AssetsCore.ckey_spriteatlas) {
                    string path0 = path.Split(new string[] { "Resources/" }, StringSplitOptions.RemoveEmptyEntries)[1];
                    SpriteAtlas atlas = Resources.Load<SpriteAtlas>(path0);
                    Sprite[] array = new Sprite[atlas.spriteCount];
                    atlas.GetSprites(array);
                    for (int i = 0; i < array.Length; i++) {
                        S_WriteOnlyPath(onlyPath_PathDic, array[i].name, fullPath, extension);
                    }
                } else {
                    S_WriteOnlyPath(onlyPath_PathDic, name, fullPath, extension);
                }
            }
            //---------排序-----------------------------------
            Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic2 = new Dictionary<string, Dictionary<C_Int4, string>>();
            var dic0 = onlyPath_PathDic.GetEnumerator();
            while (dic0.MoveNext()) {
                var dic = dic0.Current.Value.GetEnumerator();
                onlyPath_PathDic2[dic0.Current.Key]= dic0.Current.Value.OrderBy(n => n.Key.o_id).ToDictionary(n => n.Key, n => n.Value);
            }
            return onlyPath_PathDic2;
        }


        static void S_WriteOnlyPath(Dictionary<string, Dictionary<C_Int4, string>> onlyPath_PathDic, string name, string path,string extension) {
            if (onlyPath_PathDic.ContainsKey(extension) == false) {
                onlyPath_PathDic[extension] = new Dictionary<C_Int4, string>();
            }
            C_Int4 onlyPath = C_Int4.Get(name);
            if (onlyPath != C_Int4.zero) {
                onlyPath_PathDic[extension][onlyPath] = path;
            }
        }



        #endregion-------------------------------


    }





}